#ifndef GRAPHICSITEMS_H
#define GRAPHICSITEMS_H

#include "LeGraphicsView/LeGraphicsItem.h"

#include "LeIpc7351/Terminal.h"
#include "LeIpc7351/Primitives/RectanglePrimitive.h"

#include <QStyleOptionGraphicsItem>

//class RectangleItem: public LeGraphicsItem
//{
//    Q_OBJECT

//public:
//    enum
//    {
//        Type = UserType + 0x1100,
//    };

//    RectangleItem(const RectanglePrimitive *primitive);
//    ~RectangleItem();

//    // QGraphicsItem interface
//public:
//    virtual int type() const override { return Type; }
//    virtual QRectF boundingRect() const override;
//    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

//    // LeGraphicsItem interface
//public:
//    virtual LeGraphicsItem *clone() const override;

//};

class TerminalItem: public LeGraphicsItem
{
    Q_OBJECT

public:
    enum
    {
        Type = UserType + 0x1000,
    };

    explicit TerminalItem(const Terminal *terminal);
    ~TerminalItem();

    void setLabel(const QString &text);
    QString label() const;

    const Terminal *terminal() const;
    void synchronise();

private:
    const Terminal *m_terminal = nullptr;
    LeGraphicsLabelItem *m_label = nullptr;

    // QGraphicsItem interface
public:
    virtual int type() const override { return Type; }
    virtual QRectF boundingRect() const override;
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

    // LeGraphicsItem interface
public:
    virtual LeGraphicsItem *clone() const override;
};

template<class T>
class ArrangementItem: public LeGraphicsCompositeItem
{
public:
    explicit ArrangementItem(const T *arragement);
    ~ArrangementItem();

    void synchronise();

private:
    const T *m_arrangement = nullptr;
    QList<TerminalItem*> m_terminals;

    // QGraphicsItem interface
public:
    virtual int type() const override { return UserType + 0x1001; }
    virtual QRectF boundingRect() const override;
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

    // LeGraphicsItem interface
public:
    virtual LeGraphicsItem *clone() const override;
};

// FIXME

template<class T>
ArrangementItem<T>::ArrangementItem(const T *arragement)
    : LeGraphicsCompositeItem(LeGraphicsFeature::GftNone)
    , m_arrangement(arragement)
{
    // FIXME:
    setFlag(ItemHasNoContents, false);

    synchronise();
}

template<class T>
ArrangementItem<T>::~ArrangementItem()
{

}

template<class T>
void ArrangementItem<T>::synchronise()
{
    prepareGeometryChange();
    qDeleteAll(m_terminals);
    m_terminals.clear();

    const QList<Transform> transforms = m_arrangement->transforms();
    const QList<QPointF> positions = m_arrangement->positions();
    for (int i = 0; i < transforms.count(); i++)
    {
        auto item = new TerminalItem(m_arrangement->terminal());
        item->setParentItem(this);
        QTransform xform;
        if (transforms[i].mirror)
            xform.scale(-1, 1);
        xform.rotate(transforms[i].rotation);
        item->setTransform(xform);
        item->setPos(positions[i]);
        item->setLabel(QString("%1%2").arg(m_arrangement->numberingPrefix()).arg(i+1));
        m_terminals.append(item);
    }
}

template<class T>
QRectF ArrangementItem<T>::boundingRect() const
{
    return QRectF(-m_arrangement->size().width()/2.0, -m_arrangement->size().height()/2.0,
                  m_arrangement->size().width(), m_arrangement->size().height());
}

template<class T>
void ArrangementItem<T>::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(widget)

    GraphicsStyleOption itemOption;
    itemOption.exposedRect = option->exposedRect;
    itemOption.palette = layer()->graphicsPalette(featureType());
    itemOption.state = state();
    LeGraphicsStyle *style = graphicsScene()->graphicsStyle();
    style->drawRect(&itemOption, painter, boundingRect());
    //style->drawOrigin(&itemOption, painter, pos());
}

template<class T>
LeGraphicsItem *ArrangementItem<T>::clone() const
{
    return nullptr;
}
#endif // GRAPHICSITEMS_H
